%%
% @aData patrones a analizar
% @f un arreglo de fracciones de muestras a tomar del conjunto de datos (si es un escalar, se toma
%       el comportamiento por defecto, 2 muestras.
% @rep cantidad de repeticiones a hacer
% @algoritmo_agrupamiento es la funcion de agrupamiento, los parametros de
% la función deben ser: sData, una estructura que contenga un campo data
% con los datos para generar el agrupamiento y el número de particiones a
% realizar.
% @k número de clusters a buscar con el algoritmo de agrupamiento

% retorna un vector con el porcentaje de cluster similares por cada
% repetición.

% valid_external puede ser descargado de: http://www.mathworks.com/matlabcentral/fileexchange/18244
function sim = muestreo_agrupamiento (sData, f, rep, algoritmo_agrupamiento, k)

                     % Los diferentes indices, van del 1 al 4.
FOWLKES_MALLOWS = 4; % El indice de Fowlkes&Mallows, se encuentra en la posicion 4
RAND_INDEX = 1; % El indice de Fowlkes&Mallows, se encuentra en la posicion 4

coincidencias = zeros (rep,1);

if isstruct(sData)
    sData = sData.data;
end

if isscalar(f)
    % si es un escalar, utilizamos la forma por defecto. Dos repeticiones con la misma
    % cantidad fracción de datos.
    f = [f f];
end

for i = 1:rep
    disp(['Repetición ' num2str(i) '/' num2str(rep)]);
    
    % Obtenemos 2 fracciones aleatorias de datos
    len = size(sData,1);
    
    % Obtenemos una proporción c de los datos, de forma aleatoria
    [L, sub] = bmuses_para_fraccion_dato(sData, f, algoritmo_agrupamiento, k);
    
    % aplicamos clustering a cada subconjunto de datos.
    L1 = L{1};
    L2 = L{2};

    if ~isempty(L1) && ~isempty(L2)
        % índices de los datos en común entre cada uno de los subconjuntos
        [dummy, i_sub1, i_sub2] = intersect(sub{1}, sub{2});
        % versiones anteriores de matlab no tienen la variable ~ para ignorar los
        % warnigns. La borramos, por nada en especial, únicamente porque no la usamos.
        clear dummy;

        % cálculo de las coincidencias
        % valid_external es una función que calcula varios índices, entre ellos el FM
        % se puede descargar de http://www.mathworks.com/matlabcentral/fileexchange/18244
        bmus1 = L1(i_sub1);
        bmus2 = L2(i_sub2);

        tmp = valid_external(bmus1, bmus2);
        coincidencias(i, 1) = tmp(FOWLKES_MALLOWS);
        coincidencias(i, 2) = tmp(RAND_INDEX);
    else
        coincidencias(i,1) = 0;
        coincidencias(i,2) = 0;   % no existen coincidencias para éste número de k. Muy probable porque
                                  % la cantidad de clusters es mayor a la cantidad de datos con los que se
                                  % intenta hacer el algoritmo de clustering.
    end
end

sim = coincidencias;
end

%%
% Retorna de forma aleatoria los indices.
function indexes = slice_random_index(len, c)
    indexes = randperm(len);
    indexes = sort(indexes(1:c));
end

 
